package com.ruoyi.cms.utils;

import java.text.DecimalFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Random;

public class Utils {

    private static final double EARTH_RADIUS = 6378137;

    public static double calculateTotalFee(double distance, int duration, String startTime) {
        double startFee = getStartFee(startTime);
        double distanceFee = getDistanceFee(distance, startTime);
        double durationFee = getDurationFee(duration, startTime);
        double longDistanceFee = getLongDistanceFee(distance);

        return startFee + distanceFee + durationFee + longDistanceFee;
    }

    // 根据开始时间获取起步价
    private static double getStartFee(String startTime) {
        if (isInTimePeriod(startTime, "00:00", "10:00")) {
            return 14.02;
        } else if (isInTimePeriod(startTime, "16:30", "19:00")) {
            return 14.00;
        } else if (isInTimePeriod(startTime, "19:00", "21:00")) {
            return 13.50;
        } else if (isInTimePeriod(startTime, "21:00", "24:00") || isInTimePeriod(startTime, "00:00", "00:00")) {
            return 14.00;
        } else {
            return 12.80;
        }
    }

    // 根据距离和开始时间获取里程费
    private static double getDistanceFee(double distance, String startTime) {
        double baseDistance = 3.3; // 起步里程
        double extraDistance = distance - baseDistance;
        double feePerKm;

        if (extraDistance <= 0) {
            return 0;
        }

        if (isInTimePeriod(startTime, "00:00", "06:00")) {
            feePerKm = 1.69;
        } else if (isInTimePeriod(startTime, "06:00", "10:00")) {
            feePerKm = 1.46;
        } else if (isInTimePeriod(startTime, "17:00", "19:00")) {
            feePerKm = 1.26;
        } else if (isInTimePeriod(startTime, "21:00", "22:30")) {
            feePerKm = 1.76;
        } else if (isInTimePeriod(startTime, "22:30", "24:00") || isInTimePeriod(startTime, "00:00", "06:00")) {
            feePerKm = 1.69;
        } else {
            feePerKm = 1.14;
        }

        return extraDistance * feePerKm;
    }

    // 根据时长和开始时间获取时长费
    private static double getDurationFee(int duration, String startTime) {
        int baseDuration = 10; // 起步时长
        int extraDuration = duration - baseDuration;
        double feePerMinute;

        if (extraDuration <= 0) {
            return 0;
        }

        if (isInTimePeriod(startTime, "00:00", "10:00") || isInTimePeriod(startTime, "17:00", "24:00")) {
            feePerMinute = 0.52;
        } else {
            feePerMinute = 0.26;
        }

        return extraDuration * feePerMinute;
    }

    // 根据距离获取远途费
    private static double getLongDistanceFee(double distance) {
        if (distance > 40) {
            return 20 * 0.22 + (distance - 40) * 0.90;
        } else if (distance > 20) {
            return (distance - 20) * 0.22;
        } else {
            return 0;
        }
    }

    // 辅助方法：判断当前时间是否在指定时间段内
    private static boolean isInTimePeriod(String currentTime, String startTime, String endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        LocalTime currentLocalTime = LocalTime.parse(currentTime, formatter);
        LocalTime startLocalTime = LocalTime.parse(startTime, formatter);
        LocalTime endLocalTime = LocalTime.parse(endTime, formatter);

        // 判断当前时间是否在开始时间和结束时间之间（包括开始时间）
        return !currentLocalTime.isBefore(startLocalTime) && currentLocalTime.isBefore(endLocalTime) || currentLocalTime.equals(startLocalTime);
    }


    // 经纬度计算距离
    public static double calculateDistance(Double lat1, Double lon1, Double lat2, Double lon2) {
        double a = (lat1 - lat2) * (Math.PI / 180);
        double b = (lon1 - lon2) * (Math.PI / 180);

        // 根据经纬度差计算两点间的距离
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) * Math.pow(Math.sin(b / 2), 2)));

        // 将弧长乘以地球半径，得到距离，单位为米
        s = s * EARTH_RADIUS;

        // 返回距离，单位为公里
        return s / 1000;
    }

    public static int calculateTime(Date startTime, Date endTime) {

        // 将 java.util.Date 转换为 java.time.Instant
        Instant startInstant = startTime.toInstant();
        Instant endInstant = endTime.toInstant();

        // 计算时间差
        Duration duration = Duration.between(startInstant, endInstant);

        // 获取时间差中的分钟数
        long minutes = duration.toMinutes();

        // 输出结果（如果需要）
        System.out.println("时间差为：" + minutes + "分钟");

        // 由于方法签名要求返回 int 类型，确保分钟数不会超过 Integer.MAX_VALUE
        if (minutes > Integer.MAX_VALUE) {
            throw new IllegalArgumentException("时间差超过 Integer.MAX_VALUE 分钟");
        }

        // 返回分钟数（强制转换为 int，因为方法签名要求返回 int 类型）
        return (int) minutes;
    }
}
